﻿using System.Collections.Concurrent;
using TrackSystem.IO.Formula;

namespace TrackSystem.IO.Models
{
    /// <summary>
    /// 通信协议基类
    /// </summary>
    public class ProtocolBase
    {
        #region 变量定义
        /// <summary>
        /// 传感器名称
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 传感器描述
        /// </summary>
        public string Description { get; set; }
        /// <summary>
        /// 发送缓冲区
        /// </summary>
        public byte[] Tx_r { get;  set; }

        /// <summary>
        /// 接收缓冲区
        /// </summary>
        public byte[] Rx_r { get;  set; }

        /// <summary>
        /// 发送缓冲区
        /// </summary>
        public byte[] Tx_w { get;  set; }

        /// <summary>
        /// 接收缓冲区
        /// </summary>
        public byte[] Rx_w { get;  set; }

        /// <summary>
        /// 是否为文本协议
        /// </summary>
        public bool IsAscii { get; set; }

        /// <summary>
        /// 读操作通信成功计数器
        /// </summary>
        public int Succ_R { get; set;}

        /// <summary>
        /// 读操作通信失败计数器
        /// </summary>
        public int Fail_R { get; set; }
        /// <summary>
        /// 写操作通信成功计数器
        /// </summary>
        public int Succ_W { get; set; }

        /// <summary>
        /// 写操作通信失败计数器
        /// </summary>
        public int Fail_W { get; set; }

        /// <summary>
        /// 通信使能标记
        /// </summary>
        public bool Enabled { get; set; }

        /// <summary>
        /// 通信间隔, 单位ms
        /// </summary>
        public int Interval { get; }

        /// <summary>
        /// 通信时间花费时间
        /// </summary>
        public int Lapse { get; set; }

        /// <summary>
        /// 写入队列的长度
        /// </summary>
        public int QueueLen { get
            {
                return writeQueue.Count();
            }
        }

        /// <summary>
        /// 需要写入的标志
        /// </summary>
        public bool WriteFlag { get; set; }

        /// <summary>
        /// 需要初始化
        /// </summary>
        public bool NeedInit { get; set; }
        
        /// <summary>
        /// 站地址
        /// </summary>
        public int Station { get; set; }
        
        /// <summary>
        /// 装备的ID号
        /// </summary>
        public int EquipId { get; set; }

        /// <summary>
        /// 变量名称列表
        /// </summary>
        public List<string> RegNameList { get; set; }

        /// <summary>
        /// 保持待写入数据队列
        /// </summary>
        protected ConcurrentQueue<AddressAndVal> writeQueue;
        #endregion

        #region 方法定义
        /// <summary>
        /// 构造函数
        /// </summary>
        public ProtocolBase()
        {
            RegNameList = new List<string>();

            Succ_R = 0;
            Fail_R = 0;
            Succ_W = 0;
            Fail_W = 0;
            Interval = 0;
            Enabled = true;
            writeQueue = new ConcurrentQueue<AddressAndVal>();
            WriteFlag = false;

            Tx_r = new byte[1];
            Rx_r = new byte[1];
            Tx_w = new byte[1];
            Rx_w = new byte[1];
            IsAscii = false;
        }

        /// <summary>
        /// 生成读取寄存器的通讯帧
        /// </summary>
        /// <returns></returns>
        public virtual byte[] GenerateReadFrame(out int NeedRecvLen)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 根据收到的内容进行处理
        /// </summary>
        /// <returns></returns>
        public virtual bool ProcessReadFrame(byte[] buffer)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 生成写入寄存器的通讯帧
        /// </summary>
        /// <returns></returns>

        public virtual byte[] GenerateWriteFrame(out int needRecvLen)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 根据收到的内容进行处理
        /// </summary>
        /// <returns></returns>
        public virtual bool ProcessWriteFrame(byte[] buffer)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 改变变量值
        /// </summary>
        /// <param name="Index"></param>
        /// <param name="Value"></param>
        public virtual void PushRegValue(int Index, double Value)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 读取属性值
        /// </summary>
        /// <param name="idx">索引号</param>
        /// <returns></returns>
        public OperandDef GetVal(int idx)
        {
            switch (idx)
            {
                case 0: return new OperandDef(Enabled);
                case 1: return new OperandDef(Succ_R);
                case 2: return new OperandDef(Succ_W);
                case 3: return new OperandDef(Fail_R);
                case 4: return new OperandDef(Fail_W);
                case 5: return new OperandDef(Lapse);
                case 6: return new OperandDef(QueueLen);
                case 7: return new OperandDef(Tx_r);
                case 8: return new OperandDef(Rx_r);
                case 9: return new OperandDef(Tx_w);
                case 10: return new OperandDef(Rx_w);
            }
            return new OperandDef(); 
        }
        #endregion  
    }

    #region 寄存器地址、数据对
    /// <summary>
    /// 地址数据对
    /// </summary>
    public class AddressAndVal
    {
        /// <summary>
        /// 地址
        /// </summary>
        public int Address { get; set; }
        /// <summary>
        /// 数据
        /// </summary>
        public double Value { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="index"></param>
        /// <param name="value"></param>
        public AddressAndVal(int index=0, double value=0)
        {
            Address = index;
            Value = value;
        }
    }
    #endregion
}
